package worker

import (
	"errors"
	"gitee.com/jnshao/go-start/projects/crawler/engine"
	parser2 "gitee.com/jnshao/go-start/projects/crawler/zhenai/parser"
	"log"

	"gitee.com/jnshao/go-start/projects/crawler_distributed/config"
)

type SerializedParser struct {
	Name string
	Args interface{}
}

type Request struct {
	URL    string
	Parser SerializedParser
}

type ParserResult struct {
	Requests []Request
	Items    []engine.Item
}

func SerialzeRequest(r engine.Request) Request {
	name, args := r.Parser.Serialize()
	return Request{
		URL: r.URL,
		Parser: SerializedParser{
			Name: name,
			Args: args,
		},
	}
}

func DeserialzeRequest(r Request) (engine.Request, error) {
	funcp, err := DeserializeParser(r.Parser)
	if err != nil {
		return engine.Request{}, err
	}
	return engine.Request{
		URL: r.URL,
		Parser: &engine.FuncParser{
			Name:       r.Parser.Name,
			Args:       r.Parser.Args,
			ParserFunc: funcp,
		},
	}, nil
}

func DeserializeParser(s SerializedParser) (func([]byte) engine.ParserResult, error) {
	switch s.Name {
	case config.ParseCityList:
		return parser2.ParseCityList, nil
	case config.ParseCity:
		return parser2.ParseCity, nil
	default:
		return nil, errors.New("unknown parser name")
	}
}

func DeserialzeResult(r ParserResult) engine.ParserResult {
	result := engine.ParserResult{
		Items: r.Items,
	}
	for _, request := range r.Requests {
		request, err := DeserialzeRequest(request)
		if err != nil {
			log.Printf("DeserialzeResult err:  %v", err)
			continue
		}
		result.Requests = append(result.Requests, request)
	}
	return result
}

func SerialzeResult(r engine.ParserResult) ParserResult {
	result := ParserResult{
		Items: r.Items,
	}
	for _, request := range r.Requests {
		request := SerialzeRequest(request)
		result.Requests = append(result.Requests, request)
	}
	return result
}
